import React, { useState } from "react";

import type { ComponentProps } from "react";
// Import the original mapper
import MDXComponents from "@theme-original/MDXComponents";

// Import components we'd like to use across Docs
import DocCardList from "./DocCardList";
import Admonition from "@theme/Admonition";
import Tabs from "./Tabs"; // Tabs renamed to TabbedContent for backwards compat
import TabItem from "@theme/TabItem";
import BrowserOnly from "@docusaurus/BrowserOnly";
import Link from "@docusaurus/Link";
import CollapseBox from "@site/src/components/collapsible";
import TopSection from "@site/src/components/topSection";
import { useLocation } from "@docusaurus/router";
import styles from "./styles.module.scss";
import clsx from "clsx";
import Button from "../components/button/Button";

// TODO: do we want to fix this?
const TopBlock: React.FC<React.PropsWithChildren> = ({
  children,
  langSwitcher,
  dbSwitcher,
  slug,
}: any) => {
  const location = useLocation();
  return (
    <>
      {(langSwitcher || dbSwitcher) && (
        <section className="top-section">
          <TopSection
            location={location}
            langSwitcher={langSwitcher}
            dbSwitcher={dbSwitcher}
            slug={slug}
          />
        </section>
      )}
      {children}
    </>
  );
};

// TODO: we should fix this
const CodeWithResult: React.FC<{ children: React.ReactElement[] }> = ({
  children,
  outputResultText,
  expanded = false,
  ...rest
}: any) => {
  const [show, setShow] = useState<boolean>(expanded);
  return (
    <div className={styles.codeWithResult} {...rest}>
      <div className={styles.cmd}>{children[0]}</div>
      <div className={styles.result}>
        <div className={styles.showBtn} onClick={() => setShow(!show)}>
          Show {outputResultText ? outputResultText : "CLI"} results
        </div>
        {show && children[1]}
      </div>
    </div>
  );
};

// TODO: we should fix this
const SwitchTech: React.FC<React.PropsWithChildren> = ({ children }) => {
  return <p>{children}</p>;
};

const ParallelBlocks: React.FC<React.PropsWithChildren> = ({ children }) => {
  const childArray = React.Children.toArray(children).map((child) => {
    if (React.isValidElement(child)) {
      return (
        <div className="col col--6">
          <b>{child.props.content}</b>
          <div>{child}</div>
        </div>
      );
    } else {
      return (
        <div className="col col--6">
          <div>{child}</div>
        </div>
      );
    }
  });

  return (
    <div className="container">
      <div className="row">{childArray}</div>
    </div>
  );
};

const DocsLink: React.FC<React.PropsWithChildren<ComponentProps<typeof Link>>> = ({
  children,
  ...props
}) => {
  const location = useLocation();
  if (props.href?.includes("console.prisma.io")) {
    return (
      <BrowserOnly>
        {() => {
          const modifiedHref = `${props.href?.split("?")[0]}?${location.search}`;
          return (
            <Link {...props} href={modifiedHref}>
              {children}
            </Link>
          );
        }}
      </BrowserOnly>
    );
  }

  return <Link {...props}>{children}</Link>;
};

type ButtonColor = "red" | "green" | "grey" | "grey-bg" | "dark";
interface ButtonProps {
  href?: string;
  target?: string;
  block?: boolean;
  color?: ButtonColor;
  disabled?: boolean;
  arrow?: boolean;
  onClick?: any;
  arrowLeft?: boolean;
  theme?: any;
}

const ButtonLink: React.FC<React.PropsWithChildren<ButtonProps>> = ({ children, href }) => {
  return <DocsLink to={href}>{children}</DocsLink>;
};

const NavigationLinksContainer: React.FC<React.PropsWithChildren> = ({ children }) => {
  return <>{children}</>;
};

const ExternalIcon = () => (
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 12 12">
    <path
      color="inherit"
      fill="currentColor"
      d="M6 1h5v5L8.86 3.85 4.7 8 4 7.3l4.15-4.16zM2 3h2v1H2v6h6V8h1v2a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1"
    />
  </svg>
);

const StyledLink: React.FC<React.PropsWithChildren<ComponentProps<"a">>> = ({
  children,
  ...props
}) => {
  const location = useLocation();
  const url = props.href;
  if (url?.includes(".prisma.io") || url?.startsWith("/") || url?.startsWith("#"))
    return <DocsLink {...props} href={`${props.href}${location.search ? location.search : ""}`}>{children}</DocsLink>;
  else
    return (
      <a
        {...props}
        target="_blank"
        rel="openeer noreferrer"
        className={clsx(props.className, styles.externalLink)}
      >
        {children}
        <ExternalIcon />
      </a>
    );
};

const Image: React.FC<React.PropsWithChildren<ComponentProps<"img">>> = ({ ...props }) => {
  return <img {...props} className={clsx(props.className, styles.img)} />;
};

export default {
  // Re-use the default mapping
  ...MDXComponents,
  Subsections: DocCardList, // DocCardList renamed to Subsections for backwards compat
  DocCardList,
  Admonition,
  TabbedContent: Tabs, // Tabs renamed to TabbedContent for backwards compat
  Tabs,
  TabItem,
  details: CollapseBox,
  a: StyledLink,
  Link: DocsLink,
  img: Image,
  TopBlock,
  CodeWithResult,
  SwitchTech,
  table: (p: any) => (
    <div className="mdx-table">
      <table {...p}>{p.children}</table>
    </div>
  ),
  ParallelBlocks,
  ButtonLink,
  Button,
  NavigationLinksContainer,
};
